#include <cxcore.h>
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include "kes.h"
using namespace std;

IplImage * Kes::Lmain(IplImage * resim){
    CvScalar s;
  
    int **dizi,i,j;
    
//   resim = cvLoadImage("resim27.jpg",1); 
    
   IplImage* ycb = cvCreateImage(cvSize(resim->width,resim->height), IPL_DEPTH_8U, 3);
   IplImage* yeni = cvCreateImage(cvSize(resim->width,resim->height), IPL_DEPTH_8U, 3);
    if( !resim )
        cout << "Resim acmada sorun!";

    int max_y=0,yt;
    int sum = 0, sum_r = 0, sum_g = 0, sum_b = 0, r, g, b;
    cvCvtColor(resim,ycb,CV_BGR2YCrCb);
    for(i=0;i<(ycb->height)-1;i++){
      for(j=0;j<(ycb->width)-1;j++){
         s=cvGet2D(ycb,i,j);
         if (s.val[0] > max_y) max_y =(int)s.val[0];
           }
        }
        
        yt = static_cast<int> (0.95 * (double)max_y);
        
         
        
   for(i=0;i<(resim->height)-1;i++){
      for(j=0;j<(resim->width)-1;j++){
         if ((int)((uchar *)(ycb->imageData + i*ycb->widthStep))[j*ycb->nChannels + 0] >= yt){
   			sum_r +=(int)((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 2];
			sum_g +=(int)((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 1];
			sum_b +=(int)((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 0];
			sum++;
            }
           }
        }
   for(i=0;i<(resim->height)-1;i++){
      for(j=0;j<(resim->width)-1;j++){
		if (sum >= 100) {
			r = (sum * 255 * (int)((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 2]) / sum_r;
			g = (sum * 255 * (int)((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 1]) / sum_g;
			b = (sum * 255 * (int)((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 0]) / sum_b;
			((uchar *)(yeni->imageData + i*yeni->widthStep))[j*yeni->nChannels + 2] = (r > 255) ? 255 : r;
			((uchar *)(yeni->imageData + i*yeni->widthStep))[j*yeni->nChannels + 1] = (g > 255) ? 255 : g;
			((uchar *)(yeni->imageData + i*yeni->widthStep))[j*yeni->nChannels + 0] = (b > 255) ? 255 : b;
		}else{
	((uchar *)(yeni->imageData + i*yeni->widthStep))[j*yeni->nChannels + 0]=((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 0];
    ((uchar *)(yeni->imageData + i*yeni->widthStep))[j*yeni->nChannels + 1]=((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 1]; 
    ((uchar *)(yeni->imageData + i*yeni->widthStep))[j*yeni->nChannels + 2]=((uchar *)(resim->imageData + i*resim->widthStep))[j*resim->nChannels + 2];
        }
           }
        }
       return yeni;
        cvReleaseImage( &resim );
        cvReleaseImage( &ycb );
        cvReleaseImage( &yeni );  
         }
         
IplImage * Kes::Smain(IplImage * resim){
         
    CvScalar s,s1;
    int i,j,Y,Cb,Cr;
    IplImage* ycb = cvCreateImage(cvSize(resim->width,resim->height), IPL_DEPTH_8U, 3);
    IplImage* skin = cvCreateImage(cvSize(resim->width,resim->height), IPL_DEPTH_8U, 3);
    IplImage* mask = cvCreateImage(cvSize(resim->width,resim->height), IPL_DEPTH_8U, 1);
    cvCvtColor(resim,ycb,CV_BGR2YCrCb);

    CvMat *cb = cvCreateMat( resim->height, resim->width, CV_32FC1);
    CvMat *cr = cvCreateMat( resim->height, resim->width, CV_32FC1);
    
    const unsigned char Kl = 125;
    const unsigned char Kh = 188;
    const float Wcb = 46.97;
    const unsigned char WLcb = 23;
    const unsigned char WHcb = 14;
    const float Wcr = 38.76;
    const unsigned char WLcr = 20;
    const unsigned char WHcr = 10;
    const unsigned char Ymin = 16;
    const unsigned char Ymax = 235;    
    float CbP, CrP,WcbY,WcrY,CbBarY,CrBarY;
    float a2=644.6521;
    float b2=196.8409,x,y;
   for(i=0;i<(ycb->height)-1;i++){
      for(j=0;j<(ycb->width)-1;j++){
         s=cvGet2D(ycb,i,j);
         Y=(int)s.val[0];
         Cr=(int)s.val[1];
         Cb=(int)s.val[2];
         if (Y >= Kl && Y <= Kh){
          CbP = Cb;
          CrP = Cr;
         }else{
             if (Y < Kl){
              WcbY = WLcb + ((Y - Ymin) * (Wcb - WLcb)) / (Kl - Ymin);
              WcrY = WLcr + ((Y - Ymin) * (Wcr - WLcr)) / (Kl - Ymin);
    
              CbBarY = 108 + ((Kl - Y) * (118 - 108)) / (Kl - Ymin);
              CrBarY = 154 - ((Kl - Y) * (154 - 144)) / (Kl - Ymin);
             }else{ 
              WcbY = WHcb + ((Ymax - Y) * (Wcb - WHcb)) / (Ymax - Kh);
              WcrY = WHcr + ((Ymax - Y) * (Wcr - WHcr)) / (Ymax - Kh);

              CbBarY = 108 + ((Y - Kh) * (118 - 108)) / (Ymax - Kh);
              CrBarY = 154 - ((Y - Kh) * (154 - 132)) / (Ymax - Kh);
             }
              CbP = (Cb - CbBarY) * (Wcb / WcbY) + CbBarY;
              CrP = (Cr - CrBarY) * (Wcr / WcrY) + CrBarY;
          }
         
    //      cvmSet(cb,i,j,CbP);
    //      cvmSet(cr,i,j,CrP);
          s.val[2]=(CbP < 0) ? 0 : ((CbP > 255) ? 255: static_cast <BYTE> (CbP));
          s.val[1]=(CrP < 0) ? 0 : ((CrP > 255) ? 255: static_cast <BYTE> (CrP));
          CbP=(float)s.val[2];
          CrP=(float)s.val[1];
          
          x=(cos(2.53)*(CbP-109.38)+ sin(2.53)*(CrP-152.02));
          y=((-1)*sin(2.53)*(CbP-109.38)+ cos(2.53)*(CrP-152.02));
          //printf("%d %d\n",(int)CbP,(int)CrP);
         // fprintf(fp,"%f %f\n",x,y);
          if(((pow((x-1.6),2)/a2)+(pow((y-2.41),2)/b2))<1.0){
          s1.val[0]=255;                                               
          }else{
          s1.val[0]=0;
          } 

          cvSet2D(skin,i,j,s);
          cvSet2D(mask,i,j,s1);
          
          
       }
    }

    cvReleaseMat(&cb);
    cvReleaseMat(&cr);

    return mask;

        cvReleaseImage( &mask );
            cvReleaseImage( &skin );
            cvReleaseImage( &resim );
                cvReleaseImage( &ycb);
}


IplImage * Kes::Mmain(IplImage * m){
         
          CvScalar cm,cm2;
          int i,j;
          double scr=0.0,scrcb=0.0,nu,n,cr,crb;
          CvMat *mou = cvCreateMat( m->height, m->width, CV_32FC1);
          CvMat *cr2 = cvCreateMat( m->height, m->width, CV_32FC1);
          CvMat *crcb = cvCreateMat( m->height, m->width, CV_32FC1);
          IplImage* son = cvCreateImage(cvSize(m->width,m->height), IPL_DEPTH_8U, 1);
    for(i=0;i<(m->height)-1;i++){
      for(j=0;j<(m->width)-1;j++){
          cm=cvGet2D(m,i,j);                       
          cvmSet(cr2,i,j,pow((double)cm.val[1],2));                          
          cvmSet(crcb,i,j,(double)(cm.val[1]/cm.val[2]));
      }
    }      
    cvNormalize(cr2,cr2,0,255, CV_MINMAX, 0);
    cvNormalize(crcb,crcb,0,255, CV_MINMAX, 0);
          
    for(i=0;i<(m->height)-1;i++){
      for(j=0;j<(m->width)-1;j++){
          scr+=cvmGet(cr2,i,j);
          scrcb+=cvmGet(crcb,i,j);        
      }
    }          
    n=m->height*m->width;
    nu=0.95*((scr/n)/(scrcb/n));
    
    for(i=0;i<(m->height)-1;i++){
      for(j=0;j<(m->width)-1;j++){
       cr=cvmGet(cr2,i,j);
       crb=cvmGet(crcb,i,j);                 
       cvmSet(mou,i,j,cr*pow((cr-(nu*crb)),2));                          
      }
    }                    
    cvNormalize(mou,mou,0,255, CV_MINMAX, 0);            
    for(i=0;i<(m->height)-1;i++){
      for(j=0;j<(m->width)-1;j++){
       cm2.val[0]= cvmGet(mou,i,j);   
       cvSet2D(son,i,j,cm2);                      
      }
    }
    cvDilate(son,son,NULL,1);
   cvThreshold(son, son, 150, 255, CV_THRESH_BINARY);
  //  cvDilate(son,son,NULL,1);
    return son;

    cvReleaseMat(&mou);
    cvReleaseMat(&cr2);
    cvReleaseMat(&crcb);
}
void Kes::Kmain(IplImage* resim,IplImage* gr,IplImage* mo){

     int w,h;
   CvRect bndRect = cvRect(0,0,0,0);
   CvRect mRect = cvRect(0,0,0,0);
   CvMemStorage* storage = cvCreateMemStorage(0);
   CvSeq* contour = 0;
   CvSeq* contour1 = 0;
   cvFindContours( gr, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
   cvFindContours( mo, storage, &contour1, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
   CvPoint pt1, pt2;
   CvPoint ma1, ma2;
      CvPoint ptm1, ptm2;
   CvPoint mam1, mam2;
   ma1.x=1;
   ma2.x=1;
   ma1.y=1;
   ma2.y=1;
      mam1.x=1;
   mam2.x=1;
   mam1.y=1;
   mam2.y=1;
    for( ; contour1 != 0; contour1 = contour1->h_next ){
   mRect = cvBoundingRect(contour1, 0);
   ptm1.x = mRect.x;
   ptm1.y = mRect.y;
   ptm2.x = mRect.x + mRect.width;
   ptm2.y = mRect.y + mRect.height;
   if(abs(ptm1.x-ptm2.x)>abs(mam1.x-mam2.x)){
   mam1.x=ptm1.x;
   mam2.x=ptm2.x;
   w=mRect.width;
    // if(abs(ptm1.y-ptm2.y)>abs(mam1.y-mam2.y)){
      mam1.y=ptm1.y;
      mam2.y=ptm2.y;
      h=mRect.height;
    // }
   }
//cvRectangle(resim, ptm1, ptm2, CV_RGB(0,255,0), 1);
}
 for( ; contour != 0; contour = contour->h_next ){
   bndRect = cvBoundingRect(contour, 0);
   pt1.x = bndRect.x;
   pt1.y = bndRect.y;
   pt2.x = bndRect.x + bndRect.width;
   pt2.y = bndRect.y + bndRect.height;
   
   if((((mam1.x>=(pt1.x-w/2) && mam1.x<=(pt2.x+w/2)) || (mam2.x<=(pt2.x+w/2) && mam2.x>=(pt1.x+w/2))) && (mam1.y>=(pt1.y-h/2) && mam2.y<=(pt2.y+h/2) )) && abs(pt1.x-pt2.x)>abs(ma1.x-ma2.x)){
   ma1.x=pt1.x;
   ma2.x=pt2.x;
      //   if((mam1.y>=(pt1.y-h/2) || mam2.y<=(pt2.y+h/2)) && abs(pt1.y-pt2.y)>abs(ma1.y-ma2.y)){
            ma1.y=pt1.y;
            ma2.y=pt2.y;
        // }
   }

//cvRectangle(resim, pt1, pt2, CV_RGB(255,0,0), 1);
}   

   IplImage* crop = cvCreateImage(cvSize(abs(ma2.x-ma1.x),abs(ma2.y-ma1.y)), IPL_DEPTH_8U, 3);

   printf("Buyuk:\n%d %d\n%d %d\n\n",ma1.x,ma1.y,ma2.x,ma2.y);
   printf("Buyukm:\n%d %d\n%d %d\n\n",mam1.x,mam1.y,mam2.x,mam2.y);
  // cvRectangle(resim, ma1, ma2, CV_RGB(255,0,0), 1);
  // cvRectangle(resim, mam1, mam2, CV_RGB(0,0,255), 1);
   cvNamedWindow("My Window1", CV_WINDOW_AUTOSIZE);
   cvShowImage("My Window1",resim);
   
   mRect = cvRect(ma1.x,ma1.y,abs(ma2.x-ma1.x),abs(ma2.y-ma1.y));
   cvSetImageROI(resim,mRect);
   cvCopy(resim,crop,0);
   cvSaveImage("crop.jpg",crop);
   cvNamedWindow("My Window", CV_WINDOW_AUTOSIZE);
   cvShowImage("My Window",resim);
    cvWaitKey(20000);
    cvReleaseImage(&gr);
    cvReleaseImage(&crop);
    cvReleaseImage(&resim);
    cvDestroyWindow("My Window");
    cvDestroyWindow("My Window1");
}
